package com.pearadmin.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pearadmin.common.tools.SequenceUtil;
import com.pearadmin.common.web.domain.request.PageDomain;
import com.pearadmin.modules.sys.domain.*;
import com.pearadmin.modules.sys.domain.dto.AnodeBlockDto;
import com.pearadmin.modules.sys.domain.vo.WorkOperateCheckVO;
import com.pearadmin.modules.sys.mapper.WorkOperateAnodeHistoryMapper;
import com.pearadmin.modules.sys.mapper.WorkOperateAnodeMapper;
import com.pearadmin.modules.sys.mapper.WorkOperateDetailMapper;
import com.pearadmin.modules.sys.mapper.WorkOperateMapper;
import com.pearadmin.modules.sys.service.ISysDeptService;
import com.pearadmin.modules.sys.service.IWorkOperateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 运行工作记录Service业务层处理
 *
 * @author Mr.Ling
 * @date 2021-11-26
 */
@Service
public class WorkOperateServiceImpl implements IWorkOperateService {
    @Autowired
    private WorkOperateMapper workOperateMapper;
    @Autowired
    private WorkOperateAnodeMapper workOperateAnodeMapper;
    @Autowired
    private WorkOperateAnodeHistoryMapper historyMapper;
    @Autowired
    private WorkOperateDetailMapper workOperateDetailMapper;
    @Autowired
    private ISysDeptService deptService;

    /**
     * 查询运行工作记录
     *
     * @param id 运行工作记录ID
     * @return 运行工作记录
     */
    @Override
    public WorkOperate selectWorkOperateById(String id) {
        return workOperateMapper.selectWorkOperateById(id);
    }

    /**
     * 查询运行工作记录列表
     *
     * @param workOperate 运行工作记录
     * @return 运行工作记录
     */
    @Override
    public List<WorkOperate> selectWorkOperateList(WorkOperate workOperate) {
        return workOperateMapper.selectWorkOperateList(workOperate);
    }

    /**
     * 查询运行工作记录
     *
     * @param workOperate 运行工作记录
     * @param pageDomain
     * @return 运行工作记录 分页集合
     */
    @Override
    public PageInfo<WorkOperate> selectWorkOperatePage(WorkOperate workOperate, PageDomain pageDomain) {
        PageHelper.startPage(pageDomain.getPage(), pageDomain.getLimit());
        List<WorkOperate> data = workOperateMapper.selectWorkOperateList(workOperate);
        return new PageInfo<>(data);
    }

    /**
     * 运行工作记录
     * 根据工作类型来进行划分
     * - 装入 --》需要保存或者更新阳极当前在工位上的信息
     * - 吊出---》如果有异常 --》需要保存异常类型的次数---对后续的报表进行汇总使用
     * @param workOperate 运行工作记录
     * @return 结果
     */
    @Override
    @Transactional
    public int insertWorkOperate(WorkOperate workOperate) {
        //处于装入的时候判断在位情况
        if ("in".equals(workOperate.getOperateType())) {
            //根据槽号极号查询是否存在数据，在位新增
            WorkOperateAnode anode = workOperateAnodeMapper.findBySlotAndPole(workOperate.getSlotNo(), workOperate.getPoleNo());
            //开始更新数据
            if (anode == null) {
                saveCurrentAndHistory(workOperate);
            }else {
                updateCurrentAndHistory(workOperate);
            }
        } else if ("out".equals(workOperate.getOperateType())) {
            updateCurrentAndHistory(workOperate);
        }
        //处理吊出类型新增异常报告
        if (workOperate.getContent() != null) {
            saveAbnormalInfo(workOperate);
        }
        workOperate.setCreateTime(LocalDateTime.now());
        return workOperateMapper.insertWorkOperate(workOperate);
    }

    private void updateCurrentAndHistory(WorkOperate workOperate) {
        WorkOperateAnode anode = workOperateAnodeMapper.findBySlotAndPole(workOperate.getSlotNo(), workOperate.getPoleNo());
        WorkOperateAnode workOperateAnode = BeanUtil.copyProperties(workOperate, WorkOperateAnode.class);
        workOperateAnode.setId(anode.getId());
        if ("in".equals(workOperate.getOperateType())) {
            workOperateAnode.setStatus("1");
        } else if ("out".equals(workOperate.getOperateType())) {
            workOperateAnode.setStatus("0");
        }
        workOperateAnodeMapper.updateWorkOperateAnode(workOperateAnode);
        WorkOperateAnodeHistory workOperateAnodeHistory = BeanUtil.copyProperties(workOperateAnode, WorkOperateAnodeHistory.class);
        if ("in".equals(workOperate.getOperateType())) {
            workOperateAnodeHistory.setType("in");
        } else if ("out".equals(workOperate.getOperateType())) {
            workOperateAnodeHistory.setType("out");
        }
        workOperateAnodeHistory.setId(SequenceUtil.makeStringId());
        workOperateAnodeHistory.setCreateTime(LocalDateTime.now());
        historyMapper.insertWorkOperateAnodeHistory(workOperateAnodeHistory);
    }

    //保存吊出异常的数据记录
    private void saveAbnormalInfo(WorkOperate workOperate) {
        String content = workOperate.getContent();
        JSONObject parse = JSONUtil.parseObj(content);
        JSONArray abnormal = JSONUtil.parseArray(parse.get("abnormal"));
        if (!abnormal.isEmpty()) {
            WorkOperateDetail detail = BeanUtil.copyProperties(workOperate, WorkOperateDetail.class);
            detail.setId(SequenceUtil.makeStringId());
            detail.setOperateId(workOperate.getId());
            for (Object type : abnormal) {
                if ("crack".equals(type.toString())) {
                    detail.setCrackNum(1);
                } else if ("drop".equals(type.toString())) {
                    detail.setDropNum(1);
                } else if ("high".equals(type.toString())) {
                    detail.setHighNum(1);
                } else if ("thin".equals(type.toString())) {
                    detail.setThinNum(1);
                } else if ("claw".equals(type.toString())) {
                    detail.setClawNum(1);
                } else if ("other".equals(type.toString())) {
                    detail.setOtherNum(1);
                }
            }
            workOperateDetailMapper.insertWorkOperateDetail(detail);
        }
    }

    //保存当前在位情况和历史在位情况
    private void saveCurrentAndHistory(WorkOperate workOperate) {
        WorkOperateAnode workOperateAnode = BeanUtil.copyProperties(workOperate, WorkOperateAnode.class);
        workOperateAnode.setStatus("1");
        workOperateAnode.setId(SequenceUtil.makeStringId());
        workOperateAnodeMapper.insertWorkOperateAnode(workOperateAnode);
        WorkOperateAnodeHistory workOperateAnodeHistory = BeanUtil.copyProperties(workOperateAnode, WorkOperateAnodeHistory.class);
        workOperateAnodeHistory.setType("in");
        workOperateAnodeHistory.setId(SequenceUtil.makeStringId());
        workOperateAnodeHistory.setCreateTime(LocalDateTime.now());
        historyMapper.insertWorkOperateAnodeHistory(workOperateAnodeHistory);
    }

    public String deptNameByDeptId(String deptId) {
        SysDept dept = deptService.getById(deptId);
        return dept.getDeptName();
    }

    /**
     * 修改运行工作记录
     *
     * @param workOperate 运行工作记录
     * @return 结果
     */
    @Override
    public int updateWorkOperate(WorkOperate workOperate) {
        return workOperateMapper.updateWorkOperate(workOperate);
    }

    /**
     * 删除运行工作记录对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteWorkOperateByIds(String[] ids) {
        return workOperateMapper.deleteWorkOperateByIds(ids);
    }

    /**
     * 删除运行工作记录信息
     *
     * @param id 运行工作记录ID
     * @return 结果
     */
    @Override
    public int deleteWorkOperateById(String id) {
        return workOperateMapper.deleteWorkOperateById(id);
    }

    @Override
    public WorkOperateCheckVO findByOrderId(String orderId) {
        List<WorkOperate> wos = workOperateMapper.findByOrderId(orderId);
        WorkOperateCheckVO vo = new WorkOperateCheckVO();
        List<AnodeBlockDto> list = new ArrayList<>();
        if (!CollectionUtil.isEmpty(wos)) {
            vo.setFactoryName(wos.get(0).getFactoryName());
            vo.setWorkShopName(wos.get(0).getWorkShopName());
            vo.setWorkSpaceName(wos.get(0).getWorkSpaceName());
            vo.setClassInfoName(wos.get(0).getClassInfoName());
            //组装数据
            for (WorkOperate wo : wos) {
                AnodeBlockDto dto = BeanUtil.copyProperties(wo, AnodeBlockDto.class);
                list.add(dto);
            }
            vo.setList(list);
        }
        return vo;
    }
}
